#include "app_serial.h"
#include "log/log.h"

int app_serial_init(Device *dev)
{
    app_serial_setBraudRate(dev, BR_9600); //匹配蓝牙模块的初始波特率
    
    app_serial_setParity(dev, Parity_NONE); //无校验
    app_serial_setStopBits(dev, SB_1); //1位停止位
    app_serial_setRaw(dev);
    // 刷新串口设置
    if (tcflush(dev->fd, TCIOFLUSH) < 0)
    {
        log_error("tcflush error");
        return -1;
    }
    log_debug("serial init success");

    return 0;
}

int app_serial_setBraudRate(Device *device, BraudRate baud_rate)
{
    struct termios attr;
    //获取串口属性
    if (tcgetattr(device->fd, &attr) < 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    //设置波特率
    cfsetispeed(&attr, baud_rate);
    //设置串口属性 (TCSAFLUSH： 当前不生效， 刷新时才生效)
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) < 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    log_debug("set baud rate success");
    return 0;
}

int app_serial_setParity(Device *device, Parity parity)
{
    struct termios attr;
    //获取串口属性
    if (tcgetattr(device->fd, &attr) < 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    //设置校验
    attr.c_cflag &= ~(PARENB | PARODD); //清除校验位
    attr.c_cflag |= parity;
    //设置串口属性 (TCSAFLUSH： 当前不生效， 刷新时才生效)
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) < 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    log_debug("set parity success");
    return 0;
}

int app_serial_setStopBits(Device *device, StopBits stop_bits)
{
    struct termios attr;
    //获取串口属性
    if (tcgetattr(device->fd, &attr) < 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    //设置停止位
    attr.c_cflag &= ~CSTOPB; //清除停止位
    attr.c_cflag |= stop_bits;
    //设置串口属性 (TCSAFLUSH： 当前不生效， 刷新时才生效)
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) < 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    log_debug("set stop bits success");
    return 0;
}

int app_serial_setBlock(Device *device, int is_block)
{
    struct termios attr;
    //获取串口属性
    if (tcgetattr(device->fd, &attr) < 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    // 修改属性(阻塞模式)
    if (is_block == 1)
    {
        attr.c_cc[VMIN] = 1; // 至少读取一个字符
        attr.c_cc[VTIME] = 0; // 没有数据时一直等待
    }
    else
    {
        attr.c_cc[VMIN] = 0; // 可以读不到字符
        attr.c_cc[VTIME] = 2; // 等待 2*100ms
    }
    //设置串口属性 (TCSAFLUSH： 当前不生效， 刷新时才生效)
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) < 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    log_debug("set block success");

    return 0;
}

int app_serial_setRaw(Device *device)
{
    struct termios attr;
    //获取串口属性
    if (tcgetattr(device->fd, &attr) < 0)
    {
        log_error("tcgetattr error");
        return -1;
    }
    //设置原始模式
    cfmakeraw(&attr);
    //设置串口属性 (TCSAFLUSH： 当前不生效， 刷新时才生效)
    if (tcsetattr(device->fd, TCSAFLUSH, &attr) < 0)
    {
        log_error("tcsetattr error");
        return -1;
    }
    log_debug("set raw success");

    return 0;
}
